const bcostars = require("../tars/TransactionTars").bcostars;
const {ethers} = require("ethers");
const fs = require("fs");
const {ECDSAUtils} = require("../utils/ecdsa_util");
const DataUtils = require("../utils/data_utils").DataUtils;
const FileUtils = require("../utils/file_utils").FileUtils;
const TxUtils = require("../utils/tx_utils").TxUtils;
/*var a = "0xad24a5d24d49c97f10caa5b6328120eaef65c8242edb75d1a1153608861043a34db26f454c4125f0ce666c327e831b3a78f3be74b478af2ffaac7d6a089c13a00";
        var b = ethers.getBytes(a);
        console.log(b);
*/
var privkey = "255f01b066a90853a0aa18565653d7b944cd2048c03613a9ff31cb9df9e693e5";
//合约相关的一些测试桩数据
var ContractUtil = require("../utils/contract_utils.js").ContractUtil;
var abifile = './contracts/HelloWorld6.abi';
var contractutil = ContractUtil.loadAbiFile(abifile)
var to_address = "0xbe6e9bef148d9c3ac77f28c426e609ea7b7e437a";

//var sampleAddress = "0x86886c3b49bdce8284e51f340e72f1761e6fb22f";

//先构建调用合约接口的function inputs
//ethers.js风格：指定方法名和参数，生成abi编码过的functiondata
var funcdata_hex = contractutil.abiInterface.encodeFunctionData("set", ["test8881"+DataUtils.bigIntRandom().toString()]);
console.log("encode func Data: ", funcdata_hex.length, funcdata_hex);
//类似这种格式 202 0x4ed3885e000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000077465737431323300000000000000000000000000000000000000000000000000\n'

//call接口测试数据
//var encodecallData = contractutil.abiInterface.encodeFunctionData("get",[]);
//console.log("encodeCalldata:",encodecallData)

//构建一个TransactionData的测试桩数据
var bindata = ethers.getBytes(funcdata_hex);
var toAddress = to_address;
var txData = new bcostars.TransactionData(); //包含方法调用数据
txData.version = 1;
txData.chainID = "chain0";
txData.groupID = "group0";
txData.input.readFromObject(Buffer.from(bindata)); //从bindata往tars的BinBuffer数据字段里写,牵涉类型转换
txData.to = toAddress;
txData.blockLimit = 3613; //需要从节点查询，动态更新
txData.nonce = DataUtils.bigIntRandom().toString(); //nonce是一个整形数的字符串
//txData.nonce = '330917909996311875793135189705260793856'; //固定nonce是用来调试的，多次发给节点会导致nonceChecker错误
console.log("TxData:", txData);

var debug = false;
var rawtxdata_hex = "";
var rawtxdata ="";
if (!debug) {

    //精简模式，直接调TxUtils的接口一把梭
    console.log("create_raw_transaction_by_txdata ->");
    rawtxdata = TxUtils.build_rawtransaction_by_txdata(txData, privkey);

} else {
    //测试代码，更多的打印输出
    //序列化成可以算hash的二进制串
    var txDataStream = TxUtils.build_txdata_stream(txData)
    console.log("txdata bytes:", txDataStream.length, txDataStream)
    //打印hex的txdata供调试
    var txdatahex = ethers.hexlify(Buffer.from(txDataStream));
    console.log("txdata hex ", txdatahex.length, txdatahex)
    //把txdata的hex写入文件，供调试
    FileUtils.write_file("d:/temp/txdata.txt", new Buffer.from(txdatahex));


    // 计算交易hash和进行签名
    // 2023.04.22 00:11 hash终于对上了
    // 出错时节点返回：the transaction hash does not match,originHash=cde37b41702662a17b7dc254cf1641ccbba5a5d34cc63c9add4cbf68e71a5fe6,realHash=f376f25b4651cf4
    // 原因：序列化txdata时，Buffer，Array, []互转, []里混杂着int,String导致的乱糟糟的细节问题
        var txhash = ECDSAUtils.calc_hash(txDataStream);
    console.log("hash is :", txhash);
    var txhash_bytes = ethers.getBytes("0x" + txhash);
    var txhash_hex = ethers.hexlify(txhash_bytes);
    console.log(txhash_hex);
    // 2023.04.22 01:21 sig终于签对了，注意FB3.x的签名中，v并不需要加27，和FB2.x以及跟eth不一样，就纯纯的签名即可。
    //用ethers的 wallet签名时，v是带27修正逻辑的
    /*
    var signer = new ethers.Wallet(privkey);
    console.log("address is ",signer.address)
    var sig = signer.signingKey.sign(txhash_bytes);
    //sig.v= 0;
    var sigresult = sig.serialized
    //这两行是因为3.0的签名不兼容v=27，所以强行把最后的两个字母“1b”去掉(因为是rsv的组合，v在最后一个字节，27即1b)，再补“00”
    sigresult = sigresult.substring(0,sigresult.length-2)
    sigresult = sigresult +"00"
    //用ecdsa k1的签名算法，直接签名，不要v+27或28
    */

    var sigresult = ECDSAUtils.sign(txhash_bytes, privkey);
    console.log("signresult origin:", sigresult);
//有txdata，txhash，签名，可以组装rawTransaction了
    var rawtxdata = TxUtils.build_rawtransaction_stream(txData, txhash_bytes, ethers.getBytes("0x" + sigresult));
    console.log("tars raw:", rawtxdata.length, rawtxdata);

//写到文件里，供其他模块如pythonsdk读出来直接发出去
}
var rawtxdata_hex = DataUtils.arrayToHex(rawtxdata);
console.log("tars raw hex:", rawtxdata_hex.length, rawtxdata_hex);
FileUtils.write_file("d:/temp/tx.txt", rawtxdata_hex);

